﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using  System.Xml;
using  System.Xml.Schema;
using  System.Xml.Serialization;
using  Microsoft.VisualBasic;
namespace System.Collections.Generic {
	using System;

	using System.Collections.Generic;

	using System.Text;

	using System.Xml.Serialization;



	[XmlRoot("dictionary")]

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Dictionary of serializables. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable {

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Default constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary() : base() { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dictionary">	The dictionary. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="comparer">	The comparer. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="capacity">	The capacity. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary(int capacity) : base(capacity) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="dictionary">	The dictionary. </param>
		/// <param name="comparer">		The comparer. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="capacity">	The capacity. </param>
		/// <param name="comparer">	The comparer. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="info">			The information. </param>
		/// <param name="context">	The context. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }


		#region IXmlSerializable Members

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the schema. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <returns>	The schema. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public System.Xml.Schema.XmlSchema GetSchema() {
			return null;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Reads an xml. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="reader">	The reader. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public void ReadXml(System.Xml.XmlReader reader) {

			XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

			XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));



			bool wasEmpty = reader.IsEmptyElement;

			reader.Read();



			if (wasEmpty)

				return;



			while (reader.NodeType != System.Xml.XmlNodeType.EndElement) {

				reader.ReadStartElement("item");



				reader.ReadStartElement("key");

				TKey key = (TKey)keySerializer.Deserialize(reader);

				reader.ReadEndElement();



				reader.ReadStartElement("value");

				TValue value = (TValue)valueSerializer.Deserialize(reader);

				reader.ReadEndElement();



				this.Add(key, value);



				reader.ReadEndElement();

				reader.MoveToContent();

			}

			reader.ReadEndElement();

		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Writes an xml. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="writer">	The writer. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public void WriteXml(System.Xml.XmlWriter writer) {

			XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

			XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));



			foreach (TKey key in this.Keys) {

				writer.WriteStartElement("item");



				writer.WriteStartElement("key");

				keySerializer.Serialize(writer, key);

				writer.WriteEndElement();



				writer.WriteStartElement("value");

				TValue value = this[key];

				valueSerializer.Serialize(writer, value);

				writer.WriteEndElement();



				writer.WriteEndElement();

			}

		}

		#endregion
		private const string WS_Namespace = "dimok.com";

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a dictionary schema. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="xss">	The xss. </param>
		///
		/// <returns>	The dictionary schema. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static XmlQualifiedName GetDictionarySchema(XmlSchemaSet xss) {
			XmlSchema xs = XmlSchema.Read(new StringReader(
				"<xs:schema id='DictionarySchema' targetNamespace='" + WS_Namespace +
				"' elementFormDefault='qualified' xmlns='" + WS_Namespace + "' xmlns:mstns='" +
				WS_Namespace + "' xmlns:xs='http://www.w3.org/2001/XMLSchema'>" +
				"<xs:complexType name='DictionaryType'><xs:sequence>" +
				"<xs:element name='item' type='DictionaryItem' maxOccurs='unbounded' />" +
				"</xs:sequence></xs:complexType><xs:complexType " +
				"name='DictionaryItem'><xs:sequence><xs:element name='key' " +
				"minOccurs='0' maxOccurs='1' type='xs:string' /<" +
				"<xs:element name='value' minOccurs='0' maxOccurs='1' />" +
				"</xs:sequence></xs:complexType>" +
				"<xs:element name='dictionary' type='mstns:DictionaryType'>" +
				"</xs:element></xs:schema>"),
				null);
			xss.XmlResolver = new XmlUrlResolver();
			xss.Add(xs);
			return new XmlQualifiedName("DictionaryType", WS_Namespace);
		}
	}

}
/*
 * Empty As Boolean = reader.IsEmptyElement
            reader.Read()
            If (wasEmpty) Then Return

            While reader.NodeType <> System.Xml.XmlNodeType.EndElement
                reader.ReadStartElement("item")
                Dim sKey As String = reader.ReadElementString("key")
                Dim key As String = sKey
                Dim value As TValue
                If Not GetType(TValue) Is GetType(Object) Then
                    reader.ReadStartElement("value")
                    value = CType(valueSerializer.Deserialize(reader), TValue)
                    reader.ReadEndElement()
                Else
                    value = reader.ReadElementContentAsObject()
                End If

                Me.Add(key, value)
                reader.ReadEndElement()
                reader.MoveToContent()
            End While
            reader.ReadEndElement()

        End Sub

        Public Function GetSchema() As XmlSchema Implements IXmlSerializable.GetSchema
            Return Nothing
        End Function

        Public Shared Function GetDictionarySchema(ByVal xss As XmlSchemaSet) As XmlQualifiedName
            Dim xs As XmlSchema = XmlSchema.Read(New IO.StringReader( _
              "<xs:schema id='DictionarySchema' targetNamespace='" & WS_Namespace & _
              "' elementFormDefault='qualified' xmlns='" & WS_Namespace & "' xmlns:mstns='" & _
              WS_Namespace & "' xmlns:xs='http://www.w3.org/2001/XMLSchema'>" &_
              "<xs:complexType name='DictionaryType'><xs:sequence>" &_
              "<xs:element name='item' type='DictionaryItem' maxOccurs='unbounded' />" &_
              "</xs:sequence></xs:complexType><xs:complexType " & _
              "name='DictionaryItem'><xs:sequence><xs:element name='key' " & _
              "minOccurs='0' maxOccurs='1' type='xs:string' /<" & _
              "<xs:element name='value' minOccurs='0' maxOccurs='1' />" & _
              </xs:sequence></xs:complexType>" & _
              "<xs:element name='dictionary' type='mstns:DictionaryType'>" & _
              </xs:element></xs:schema>"), _
              Nothing)
            xss.XmlResolver = New XmlUrlResolver()
            xss.Add(xs)
            Return New XmlQualifiedName("DictionaryType", WS_Namespace)
        End Function

    End Class
End Namespace
*/